package cn.kmia.hrm.service.system;

import cn.kmia.hrm.pojo.system.Permission;
import cn.kmia.hrm.pojo.system.Role;
import cn.kmia.hrm.pojo.system.User;
import cn.kmia.hrm.service.BaseService;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.QueryResult;
import org.nutz.dao.pager.Pager;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @program: java_baggage_led
 * @description: 用户服务类
 * @author: 4K
 * @create: 2018-04-16 14:39
 **/
@IocBean
public class UserService extends BaseService {

    private static final Log log = Logs.get();

    @Inject
    protected PropertiesProxy conf; // 注入配置信息加载类

    @Inject
    protected UserRoleService userRoleService;

    /**
     * 根据用户名和密码查询用户
     *
     * @param idcard
     * @param password
     * @return
     */
    public User find(String idcard, String password) {
        User user = dao.fetch(User.class, Cnd.where("user_idcard", "=", idcard));
        if (user != null) {
            String _pass = new Sha256Hash(password, user.getUser_salt()).toHex();
            if (_pass.equalsIgnoreCase(user.getUser_pwd())) {
                return user;
            }
        }
        return null;
    }

    /**
     * 新增
     *
     * @param user
     * @param opUser
     * @return
     */
    public User add(User user, String opUser) {
        user.setUser_salt(R.UU16());
        String password = conf.get("PASSWORD");
        if (password == null) {
            password = "123456";
        }
        user.setUser_pwd(new Sha256Hash(password, user.getUser_salt()).toHex());
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        user.setOpBy(opUser);
        return dao.insert(user);
    }

    /**
     * 更新
     *
     * @param user        用户信息
     * @param user_idcard 操作人
     * @return
     */
    public boolean update(User user, String user_idcard) {
        user.setOpBy(user_idcard);
        user.setUpdateTime(new Timestamp(new Date().getTime()));
        return dao.updateIgnoreNull(user) > 0 ? true : false;
    }

    /**
     * 获取用户角色和权限
     *
     * @param user
     * @return
     */
    public User getRolesAndPers(User user) {
        if (user != null) {
            // 查询角色
            user = dao.fetchLinks(user, "roles");
            if (user.getRoles() != null) {
                List<Role> roles = user.getRoles();
                List<Permission> permissions = new ArrayList<>();
                // 查询权限
                for (Role role : roles) {
                    role = dao.fetchLinks(role, "permissions");
                    if (role.getPermissions() != null) {
                        permissions.addAll(role.getPermissions());
                    }
                }
                user.setPermissions(permissions);
            }
        }
        return user;
    }

    /**
     * 重置密码
     *
     * @param ids
     * @return
     */
    @Aop(TransAop.READ_COMMITTED)
    public boolean resetPwd(int[] ids) throws Exception {
        boolean ret;
        try {
            User user;
            for (int id : ids) {
                user = dao.fetch(User.class, id);
                if (user != null) {
                    user.setUser_pwd(new Sha256Hash(conf.get("default_pwd"), user.getUser_salt()).toHex());
                    dao.update(user);
                }
            }
            ret = true;
        } catch (Exception e) {
            log.error("重置密码异常", e);
            throw e;
        }
        return ret;
    }

    /**
     * 锁定或解锁用户
     *
     * @param ids
     * @param islock
     * @return
     */
    public Object lock(int[] ids, boolean islock) {
        NutMap nm = new NutMap();
        if (ids != null && ids.length > 0) {
            nm.setv("success", dao.update(User.class, Chain.make("locked", islock), Cnd.where("id", "in", ids)));
        } else {
            nm.setv("success", false).setv("errorMsg", "请重试！");
        }
        return nm;
    }

    /**
     * 删除用户，实际标记用户delFlag为true
     *
     * @param ids
     * @return
     */
    @Aop(TransAop.READ_COMMITTED)
    public NutMap del(int[] ids) throws Exception {
        NutMap nm = new NutMap();
        if (ids != null && ids.length > 0) {
            dao.update(User.class, Chain.make("delFlag", true), Cnd.where("id", "in", ids));
            // 删除用户角色
            String idsStr = Arrays.toString(ids).substring(1, Arrays.toString(ids).length() - 1);
            userRoleService.delete(idsStr);
            nm.setv("success", true);
        } else {
            nm.setv("success", false).setv("errorMsg", "请重试！");
        }
        return nm;
    }

    /**
     * 分页查询用户
     *
     * @param idcard
     * @param name
     * @param pager
     * @return
     */
    public QueryResult queryByPage(String idcard, String name, Pager pager) {
        Cnd cnd = Cnd.where("1", "=", 1);
        if (!Strings.isBlank(idcard) && !"null".equals(idcard)) {
            cnd.and("user_idcard", "=", idcard);
        }
        if (!Strings.isBlank(name)) {
            cnd.and("user_name", "like", "%" + name + "%");
        }
        cnd.and("delFlag", "is", null);
        List<User> list = dao.queryByJoin(User.class, "roles", cnd, pager);
        List<User> rtList = new ArrayList<>();
        if (list != null && !list.isEmpty()) {
            List<Role> roleList;
            String roleNames;
            for (User user : list) {
                roleNames = "";
                roleList = user.getRoles();
                if (roleList != null) {
                    for (Role role : roleList) {
                        roleNames += role.getName() + ",";
                    }
                }
                user.setRoleNames(roleNames);
                rtList.add(user);
            }
        }
        QueryResult qr = new QueryResult();
        qr.setList(rtList);
        pager.setRecordCount(dao.count(User.class, cnd));
        qr.setPager(pager);
        return qr;
    }

    /**
     * 验证用户名是否存在
     *
     * @param idcard
     * @return
     */
    public boolean isRepeat(String idcard) {
        int count = dao.count(User.class, Cnd.where("user_idcard", "=", idcard));
        if (count > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 根据id获取user
     *
     * @param userId
     * @return
     */
    public User getUser(int userId) {
        return dao.fetch(User.class, userId);
    }

    /**
     * 重置密码
     * @param password
     * @param user
     * @return
     */
    public boolean resetPwd(String password, User user) {
        if (password != null && user != null) {
            user.setUser_salt(R.UU16());
            user.setUser_pwd(new Sha256Hash(password, user.getUser_salt()).toHex());
            return dao.update(user) > 0 ? true : false;
        }
        return false;
    }

    /**
     * 根据用户名查找用户
     * @param userName
     * @return
     */
    public User getUser(String userName) {
        return dao.fetch(User.class,Cnd.where("user_idcard","=",userName));
    }
}
